package com.lyy.cloud.utils.oss;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.*;
import com.lyy.cloud.utils.result.Result;
import com.lyy.cloud.utils.result.ResultUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Component
@Slf4j
public class OssUtil {

	public static  String endpoint = "";
	public static  String accessKeyId = "";
	public static  String accessKeySecret = "";
	public static  String bucketName = "";
	
	public static String getEndpoint() {
		return endpoint;
	}
	

	@Value("${aliyun.oss.endpoint:}")
	public  void setEndpoint(String endpoint) {
		OssUtil.endpoint = endpoint;
	}
	
	@Value("${aliyun.oss.accessKeyId:}")
	public  void setAccessKeyId(String accessKeyId) {
		OssUtil.accessKeyId = accessKeyId;
	}
	
	@Value("${aliyun.oss.accessKeySecret:}")
	public  void setAccessKeySecret(String accessKeySecret) {
		OssUtil.accessKeySecret = accessKeySecret;
	}	
	
	@Value("${aliyun.oss.bucketName:}")
	public  void setBucketName(String bucketName) {
		OssUtil.bucketName = bucketName;
	}	
	/**
	 * 保存内容 
	 * @param filepath 对象保存的完整路径
	 * @param content 内容
	 * @return 是否保存成功
	 */
	public static boolean saveObject(String filepath,String content)  throws Exception{
		if(StringUtils.isBlank(content)) {
			content = "";
		}
		OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
		ObjectMetadata metadata = new ObjectMetadata();
		metadata.setContentType("text/html");
		PutObjectRequest request = new PutObjectRequest(OssUtil.bucketName, filepath, new ByteArrayInputStream(
				content.getBytes("utf-8")),metadata);
		PutObjectResult result = ossClient.putObject(request);
		ossClient.shutdown();
		log.info("保存内容状态:{}",JSON.toJSONString(result));
		return true;
	}


	public static void putObject(String filepath,File file){
		OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
		ossClient.putObject(OssUtil.bucketName, filepath, file);
		ossClient.shutdown();
	}

	/**
	 * 保存内容 
	 * @param filepath 对象保存的完整路径
	 * @throws IOException 
	 */
	public static String getObject(String filepath) throws IOException {
		OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
		OSSObject result = ossClient.getObject(OssUtil.bucketName, filepath);
		String contentString = IOUtils.toString(result.getResponse().getContent(), "UTF-8");
		ossClient.shutdown();
		return contentString;
	}

	/**
	 * 获取内容
	 * @param filepath 对象保存的完整路径
	 * @throws IOException
	 */
	public static InputStream getInputStream(String filepath) throws IOException {
		OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
		OSSObject result = ossClient.getObject(OssUtil.bucketName, filepath);
		InputStream inputStream = result.getObjectContent();
		ossClient.shutdown();
		return inputStream;
	}
	
	public static String uploadFile(String filePath,String dir) {
        OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
        UploadFileRequest uploadFileRequest = new UploadFileRequest(OssUtil.bucketName,dir);
        
		// 待上传的本地文件
        uploadFileRequest.setUploadFile(filePath);

        // 设置并发下载数，默认1
        uploadFileRequest.setTaskNum(5);
        // 设置分片大小，默认100KB
        uploadFileRequest.setPartSize(1024 * 1024 * 1);
        // 开启断点续传，默认关闭
        uploadFileRequest.setEnableCheckpoint(true);

        UploadFileResult uploadResult;
		try {
			uploadResult = ossClient.uploadFile(uploadFileRequest);
			CompleteMultipartUploadResult multipartUploadResult = 
	                uploadResult.getMultipartUploadResult();
	        return multipartUploadResult.getLocation();
		} catch (Throwable e) {
			e.printStackTrace();
		}finally {
			ossClient.shutdown();
		}
		return null;
	}

	public static void delteObject(String delKey) {
        OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
        ossClient.deleteObject(bucketName, delKey);
        ossClient.shutdown();
	}
	
	public static List<OssFile> listObject(String dir) {
        OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
        ObjectListing list = ossClient.listObjects(bucketName,dir);
        String host = "https://" + bucketName + "." + endpoint;

        List<OssFile> files = new ArrayList<>();
        int fileNum = list.getObjectSummaries().size();
        if(fileNum>0) {
        	for(int i=0;i<fileNum;i++) {
        		String key = list.getObjectSummaries().get(i).getKey();
        		OssFile file = new OssFile();
        		file.setId(Base64Coder.encodeString(key));
        		file.setName(key.replace(dir, ""));
        		file.setUrl(host+"/"+key);
        		files.add(file);
        	}
        }
        ossClient.shutdown();
        return files;
	}
	
	/**
	 * 下载邮件
	 */
	public static File getFile(String url) {
		log.info("下载附件路径:{}",url);
		OSSClient ossClient = new OSSClient(endpoint,accessKeyId,accessKeySecret);
		try {
			boolean res = false;
			String http = "http";
			if(url.startsWith("https")) {
				http = "https";
			}
			String host = http+"://" + bucketName + "." + endpoint+"/";
			String key = url.replace(host, "");
			String filename = key.substring(key.lastIndexOf("/")+1);
			
			File file = new File(FileUtils.getTempDirectory().getPath()+File.separator+filename);
			if(file.exists()) {
				boolean delete = file.delete();
				if( !delete ){
					log.info("getFile方法删除文件失败");
				}
			}
			res = file.createNewFile();
			if(res) {
				ObjectMetadata ossObject  = ossClient.getObject(new GetObjectRequest(bucketName, key),file);
				return file;
			}
			
		} catch (Throwable e) {
			log.error("下载附件错误",e);
		}
		return null;
	}
	
	

	public static Result ossPolicy(String dir, HttpServletResponse response){
        String host = "https://" + bucketName + "." + endpoint;
        OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        String pattern = "yyyy-MM-dd'T'HH:mm:ss:SSSZZ";
        try { 	
        	long expireTime = 30;
        	long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = client.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = client.calculatePostSignature(postPolicy);
            
            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessid", accessKeyId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("expire", DateFormatUtils.format(expiration,pattern));
            respMap.put("dir", dir);
            respMap.put("host", host);
//            respMap.put("expire", String.valueOf(expireEndTime));
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Content-Type", "application/json");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST");
            return ResultUtils.wrapSuccess(respMap);
        } catch (Exception e) {
        	log.error("oss签名错误",e);
        	return ResultUtils.wrapFail(-1, "获取签名错误");
        }
	}
	
	
	@Data
	public static class OssFile{
		private String id;
		private String name ;
		private String url;
	
	}

	public static void main(String args[]) throws IOException {
		OssUtil.endpoint = "oss-cn-beijing.aliyuncs.com";
		OssUtil.accessKeyId = "234rte34234324";
		OssUtil.accessKeySecret = "234234242";
		OssUtil.bucketName = "33423322";
		long t = System.currentTimeMillis();
	}
}
